import joblib
import numpy as np
import tensorflow as tf
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler

from apps.api.mapper.sql_connect import read_data_from_db


def train():
    # X为输入特征，y为目标标签
    df = read_data_from_db()
    X = df[['Hour', 'Temperature', 'Humidity', 'WindSpeed', 'Visibility',
            'DewPointTemperature', 'SolarRadiation', 'Rainfall', 'Snowfall']].values
    y = df['RentedBikeCount'].values.reshape(-1, 1)
    # 数据预处理
    scaler = MinMaxScaler()  # 归一化数据
    X_scaled = scaler.fit_transform(X)
    y_scaled = scaler.fit_transform(y)

    # 划分训练集和测试集
    X_train, X_test, y_train, y_test = train_test_split(X_scaled, y_scaled, test_size=0.2)

    # 构建模型
    model = tf.keras.Sequential([
        tf.keras.layers.Dense(64, activation='relu', input_dim=X.shape[1]),
        tf.keras.layers.Dense(64, activation='relu'),
        tf.keras.layers.Dense(1)
    ])
    # 编译模型
    model.compile(optimizer='adam', loss='mean_squared_error')

    # 训练模型
    history = model.fit(X_train, y_train, epochs=30, batch_size=32)
    # 提取损失函数数据
    train_loss = history.history['loss']
    # 评估模型
    loss = model.evaluate(X_test, y_test)
    print("Test Loss:", loss)

    # 保存模型
    model.save("model.keras")
    joblib.dump(scaler, "scaler.pkl")
    print(train_loss)
    return train_loss


# 使用加载的模型进行预测
def predict(x_new: np.array, model_path: str = r"D:\pycharmProject\bike_system\apps\api\Model\model.keras",
            scaler_path: str = r"D:\pycharmProject\bike_system\apps\api\Model\scaler.pkl"):
    # 加载模型和预处理器
    loaded_model = tf.keras.models.load_model(model_path)
    loaded_scaler = joblib.load(scaler_path)

    # 将输入数据进行缩放
    # x_new_scaled = loaded_scaler.transform(x_new)

    # 预测
    y_pred_scaled = loaded_model.predict(x_new)

    # 将预测结果反向缩放回原始比例
    y_pred = loaded_scaler.inverse_transform(y_pred_scaled)

    # 返回预测值
    print(abs(y_pred[0][0]))
    # 返回预测值
    return int(abs(y_pred[0][0]))


predict(np.array([[1, 2, 3, 4, 5, 6, 7, 8, 9]]))
